﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ImageProcessing
{
	public enum FilterTypes{Sobel, Prewitt, Median, ArithmeticMean, GeometricMean, Min, Max, Midpoint,AlphaMean,Contraharmonic};

	public partial class FilterDialog : Form
	{
		private Bitmap _bmIn;
		private Bitmap _bmBaseTh;
		private Bitmap _bmModTh;
		private Bitmap _bmOut;
		FilterTypes _filtertype;
		private bool _imageReady;
		private bool _isPrewitt;
		private double[][][] adYIQBig;
		private double[][][] adYIQ;


		public Bitmap ImageOut
		{
			get { return _bmOut; }
			set { _bmOut = new Bitmap(value); }
		}
		public Bitmap ImageIn
		{
			set
			{
				_bmIn = new Bitmap(value);
				_imageReady = true;
				_bmBaseTh = (Bitmap)_bmIn.GetThumbnailImage(200, 200, null, IntPtr.Zero);
				_bmModTh = new Bitmap(_bmBaseTh);
				picBoxBase.Invalidate();
				picBoxModified.Invalidate();
			} //end set
		}//end ImageIn

		public FilterDialog(Bitmap bmin, FilterTypes fType)
		{
			InitializeComponent();
			ImageIn = bmin;
			adYIQBig = ColorConversions.ImageToYIQ(_bmIn);
			adYIQ = ColorConversions.ImageToYIQ(_bmModTh);

			switch (fType)
			{
				case FilterTypes.Sobel:
					cmbboxEdge.Text = "Sobel";
					break;
				case FilterTypes.Prewitt:
					cmbboxEdge.Text = "Prewitt";
					break;
				case FilterTypes.Median:
					cmbboxEdge.Text = "Median";
					break;
				case FilterTypes.ArithmeticMean:
					cmbboxEdge.Text = "Arithmetic Mean";
					break;
				case FilterTypes.GeometricMean:
					cmbboxEdge.Text = "Geometric Mean";
					break;
				case FilterTypes.Min:
					cmbboxEdge.Text = "Min";
					break;
				case FilterTypes.Max:
					cmbboxEdge.Text = "Max";
					break;
				case FilterTypes.Midpoint:
					cmbboxEdge.Text = "Midpoint";
					break;
				case FilterTypes.AlphaMean:
					cmbboxEdge.Text = "Alpha-trimmed Mean";
					break;
				case FilterTypes.Contraharmonic:
					cmbboxEdge.Text = "Contraharmonic";
					break;
				default:
					break;
			} //end switch
		} //end FilterDialog

		public FilterDialog()
		{
			InitializeComponent();
		}

		private void btnEdge_Click(object sender, EventArgs e)
		{
			switch (cmbboxEdge.Text)
			{
				case "Sobel":
					_isPrewitt = false;
					_bmModTh = EdgeFilters.SobelPrewitt(_bmBaseTh, _isPrewitt);
					_filtertype = FilterTypes.Sobel;
	
					break;
				case "Prewitt":
					_isPrewitt = true;
					_bmModTh = EdgeFilters.SobelPrewitt(_bmBaseTh, _isPrewitt);
					_filtertype = FilterTypes.Prewitt;
					
					break;
				default:
					break;
			}//end switch

			picBoxModified.Invalidate();
		}



		private void picBoxBase_Paint(object sender, PaintEventArgs e)
		{
			if (_imageReady)
				picBoxBase.BackgroundImage = _bmBaseTh;
		}

		private void picBoxModified_Paint(object sender, PaintEventArgs e)
		{
			if (_imageReady)
				picBoxModified.BackgroundImage = _bmModTh;
		}


		private void SetImageOut()
		{
			int nFilterSize;
			int nAlpha;
			try
			{
				nFilterSize = System.Convert.ToInt32(txtboxOrderStatSize.Text);
				nAlpha = System.Convert.ToInt32(txtboxOrderStatVar1.Text);
			} //end try
			catch (Exception)
			{
				txtboxOrderStatSize.Text = "";
				txtboxOrderStatVar1.Text = "";
				lblOrderStatErrorSize.Visible = true;
				lblOrderStatErrorVar.Visible = true;
				return;
			} //end catch

			switch (_filtertype)
			{
				case FilterTypes.Sobel:
					_isPrewitt = false;
					ImageOut = EdgeFilters.SobelPrewitt(_bmIn, _isPrewitt);
					break;
				case FilterTypes.Prewitt:
					_isPrewitt = true;
					ImageOut = EdgeFilters.SobelPrewitt(_bmIn, _isPrewitt);
					break;
				case FilterTypes.Median:
					ImageOut = OrderStatFilters.Median(adYIQBig, _bmIn.Height, _bmIn.Width, nFilterSize, _bmIn.PixelFormat);
					break;
				case FilterTypes.ArithmeticMean:
					ImageOut = OrderStatFilters.ArithmeticMean(adYIQBig, _bmIn.Height, _bmIn.Width, nFilterSize, _bmIn.PixelFormat);
					break;
				case FilterTypes.GeometricMean:
					ImageOut = OrderStatFilters.GeometricMean(adYIQBig, _bmIn.Height, _bmIn.Width, nFilterSize, _bmIn.PixelFormat);
					break;
				case FilterTypes.Min:
					ImageOut = OrderStatFilters.Min(adYIQBig, _bmIn.Height, _bmIn.Width, nFilterSize, _bmIn.PixelFormat);
					break;
				case FilterTypes.Max:
					ImageOut = OrderStatFilters.Max(adYIQBig, _bmIn.Height, _bmIn.Width, nFilterSize, _bmIn.PixelFormat);
					break;
				case FilterTypes.Midpoint:
					ImageOut = OrderStatFilters.MidPoint(adYIQBig, _bmIn.Height, _bmIn.Width, nFilterSize, _bmIn.PixelFormat);
					break;
				case FilterTypes.AlphaMean:
					ImageOut = OrderStatFilters.AlphaTrimMean(adYIQBig, _bmIn.Height, _bmIn.Width, nFilterSize, _bmIn.PixelFormat, nAlpha);
					break;
				case FilterTypes.Contraharmonic:
					ImageOut = OrderStatFilters.Contraharmonic(adYIQBig, _bmIn.Height, _bmIn.Width, nFilterSize, _bmIn.PixelFormat, nAlpha);
					break;
				default:
					break;
			} //end switch
		}

		private void btnOrderStat_Click(object sender, EventArgs e)
		{
			int nFilterSize;
			int nAlpha;
			try
			{
				nFilterSize = System.Convert.ToInt32(txtboxOrderStatSize.Text);
				nAlpha = System.Convert.ToInt32(txtboxOrderStatVar1.Text);
			} //end try
			catch (Exception)
			{
				txtboxOrderStatSize.Text = "";
				txtboxOrderStatVar1.Text = "";
				lblOrderStatErrorSize.Visible = true;
				lblOrderStatErrorVar.Visible = true;
				return;
				
			} //end catch

		
			lblOrderStatErrorSize.Visible = false;
			lblOrderStatErrorVar.Visible = false;
			if (nFilterSize % 2 != 1)
			{
				//even sized filter
				lblOrderStatErrorSize.Visible = true;
				txtboxOrderStatSize.Text = "";
			}

			adYIQ = ColorConversions.ImageToYIQ(_bmBaseTh);
			
			switch (cmbboxOrderStat.Text)
			{
				case "Median":
					_bmModTh = OrderStatFilters.Median(adYIQ, _bmModTh.Height, _bmModTh.Width, nFilterSize, _bmModTh.PixelFormat);
					_filtertype = FilterTypes.Median;
					break;
				case "Arithmetic Mean":
					_bmModTh = OrderStatFilters.ArithmeticMean(adYIQ, _bmModTh.Height, _bmModTh.Width, nFilterSize, _bmModTh.PixelFormat);
					_filtertype = FilterTypes.ArithmeticMean;
					
					break;
				case "Geometric Mean":
					_bmModTh = OrderStatFilters.GeometricMean(adYIQ, _bmModTh.Height, _bmModTh.Width, nFilterSize, _bmModTh.PixelFormat);
					_filtertype = FilterTypes.GeometricMean;
					
					break;
				case "Min":
					_bmModTh = OrderStatFilters.Min(adYIQ, _bmModTh.Height, _bmModTh.Width, nFilterSize, _bmModTh.PixelFormat);
					_filtertype = FilterTypes.Min;
					
					break;
				case "Max":
					_bmModTh = OrderStatFilters.Max(adYIQ, _bmModTh.Height, _bmModTh.Width, nFilterSize, _bmModTh.PixelFormat);
					_filtertype = FilterTypes.Max;
					
					break;
				case "Midpoint":
					_bmModTh = OrderStatFilters.MidPoint(adYIQ, _bmModTh.Height, _bmModTh.Width, nFilterSize, _bmModTh.PixelFormat);
					_filtertype = FilterTypes.Midpoint;

					break;
				case "Alpha-trimmed Mean":
					_bmModTh = OrderStatFilters.AlphaTrimMean(adYIQ, _bmModTh.Height, _bmModTh.Width, nFilterSize, _bmModTh.PixelFormat, nAlpha);
					_filtertype = FilterTypes.AlphaMean;
					
					break;
				case "Contraharmonic":
					_bmModTh = OrderStatFilters.Contraharmonic(adYIQ, _bmModTh.Height, _bmModTh.Width, nFilterSize, _bmModTh.PixelFormat, nAlpha);
					_filtertype = FilterTypes.Contraharmonic;
					
					break;
				default:
					break;
			} //end switch 

			picBoxModified.Invalidate();
		}

		private void btnOk_Click(object sender, EventArgs e)
		{
			this.Cursor = Cursors.WaitCursor;
			SetImageOut();
		}


		private void btnCommit_Click(object sender, EventArgs e)
		{
			_bmBaseTh = new Bitmap(_bmModTh);
			this.Cursor = Cursors.WaitCursor;
			SetImageOut();
			this.Cursor = Cursors.Default;
			picBoxBase.Invalidate();
		}
	}
}






